package com.tangyuan.user.controller;

import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.tangyuan.common.config.AliyunStsOSSConfig;
import com.tangyuan.common.result.Result;
import com.tangyuan.common.result.ResultCodeEnum;
import com.tangyuan.common.util.AliyunStsOSSUtils;
import com.tangyuan.common.util.CommStatus;
import com.tangyuan.model.User;
import com.tangyuan.vo.OssTokenVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * 阿里云OSS STS
 *
 * @author Gin
 */
@Slf4j
@RestController
@RequestMapping("/user/aliyun")
public class AliYunStsController {

    //获取 OSS 签名授权
    @GetMapping("/sts/tokens")
    public Result getOssToken(@RequestHeader(name = "Authorization") String token) {
        User user = CommStatus.getUser(token);
        if (user == null){
            return Result.build(null, ResultCodeEnum.LOGIN_AUTH);
        }

        // 获取缓存实例
        OssTokenCache cache = OssTokenCache.getInstance();
        // 从缓存中获取用户的令牌
        OssTokenVO cachedToken = cache.getCachedToken(String.valueOf(user.getId()));

        // 如果缓存中有有效的令牌，直接返回
        if (cachedToken != null) {
            return Result.ok(cachedToken);
        }

        // long startTime = System.currentTimeMillis();
        AssumeRoleResponse ossToken = AliyunStsOSSUtils.createOssToken();
        if (Objects.isNull(ossToken)) {
            return Result.fail("获取 OSS 签名授权失败！");
        }

        AssumeRoleResponse.Credentials credentials = ossToken.getCredentials();
        OssTokenVO ossTokenVO = OssTokenVO.builder()
                .region("oss-cn-qingdao.aliyuncs.com") //地域名
                .accessKeyId(credentials.getAccessKeyId())
                .accessKeySecret(credentials.getAccessKeySecret())
                .securityToken(credentials.getSecurityToken())
                .expiration(credentials.getExpiration())
                // OSS bucket名称
                .bucket("shengtangfeng1")
                .build();
        // 缓存新的令牌
        cache.cacheToken(String.valueOf(user.getId()), ossTokenVO);
        return Result.ok(ossTokenVO);
    }

}

// 单例类，负责缓存OSS令牌
class OssTokenCache {

    private static final long CACHE_EXPIRATION_TIME = TimeUnit.MINUTES.toMillis(15); // 缓存有效时间15分钟
    private static OssTokenCache instance; // 单例实例
    private final ConcurrentHashMap<String, CachedOssToken> tokenCache; // 存储令牌的缓存

    private OssTokenCache() {
        tokenCache = new ConcurrentHashMap<>();
    }

    // 获取单例实例
    public static synchronized OssTokenCache getInstance() {
        if (instance == null) {
            instance = new OssTokenCache();
        }
        return instance;
    }

    // 缓存令牌
    public void cacheToken(String userId, OssTokenVO token) {
        tokenCache.put(userId, new CachedOssToken(token, System.currentTimeMillis()));
    }

    // 获取缓存的令牌，如果超过有效期则返回null
    public OssTokenVO getCachedToken(String userId) {
        CachedOssToken cachedOssToken = tokenCache.get(userId);
        if (cachedOssToken == null) {
            return null;
        }
        // 检查是否超过有效期
        if (System.currentTimeMillis() - cachedOssToken.timestamp > CACHE_EXPIRATION_TIME) {
            tokenCache.remove(userId);
            return null;
        }
        return cachedOssToken.token;
    }

    // 内部类，包含令牌和时间戳
    private static class CachedOssToken {
        private final OssTokenVO token;
        private final long timestamp;

        private CachedOssToken(OssTokenVO token, long timestamp) {
            this.token = token;
            this.timestamp = timestamp;
        }
    }
}


